import { Action, ExecuteResult, ExecuteStatus, ExecutiveContext, State } from "../defination"
import { Executive } from "../defination"
import { ActivityRecord, ByteArray, ExecutionRecord, ExecutiveRecord, LockRecord } from "../entity"
import { ACTIVITY,PREVIOUS,NEXT, STATE_RECORD, EXECUTION_RECORD, RESULT, ACTION, ACTIVITY_STATUS, EXECUTE_STATUS, DEALER } from "../shared-symbols"
import { readonly } from "../readonly"
import { DealResult } from "../deal-result"


export class BaseAction
<
  TActivity extends Executive<TActivity,TState,TRecord,TContext>,
  TState extends State=State,
  TRecord extends ExecutiveRecord=ExecutiveRecord,
  TContext extends ExecutiveContext=ExecutiveContext
> implements Action<TActivity,TState,TRecord,TContext>
{

  [ACTIVITY]:TActivity
  [STATE_RECORD]:TRecord
  [EXECUTION_RECORD]?:ExecutionRecord
  [RESULT]?:DealResult
  [PREVIOUS]?:BaseAction<TActivity,TState,TRecord,TContext>
  [NEXT]?:BaseAction<TActivity,TState,TRecord,TContext>|null|undefined
 

  constructor(act:TActivity|BaseAction<TActivity,TState,TRecord,TContext>){
    
    if(act instanceof BaseAction){
      this[ACTIVITY] = act[ACTIVITY]
      this[STATE_RECORD] = act[STATE_RECORD]
      this[EXECUTION_RECORD] = act[EXECUTION_RECORD]
      this[PREVIOUS] = act
      this[NEXT] =undefined
    }else {

      this[ACTIVITY] = act
      this[STATE_RECORD] = act[STATE_RECORD]
      this[PREVIOUS] = undefined
      this[NEXT] = undefined
    }
  }

  get activity():TActivity{ 
    return this[ACTIVITY]
  }
  get activityRecord():TRecord{
    return readonly(this[STATE_RECORD])
  }
  get executionRecord():ExecutionRecord|undefined{
    return readonly(this[EXECUTION_RECORD])
  }
  get previous():BaseAction<TActivity,TState,TRecord,TContext>|undefined{
    return this[PREVIOUS]
  }
  get next():BaseAction<TActivity,TState,TRecord,TContext>|null|undefined{ 
    throw new Error('not implemented')
  }
  get result():DealResult|undefined{
    return this[RESULT]
  } 
  async invoke(context:TContext):Promise<BaseAction<TActivity,TState,TRecord,TContext>|null|undefined>{
    return this[NEXT] = this.next!
  }

  
}